package com.jbp.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jbp.dao.UserNobilityDao;
import com.jbp.model.User;
import com.jbp.model.UserNobility;
import com.jbp.redis.RedisConfigService;
import com.jbp.service.UserNobilityService;
import com.jbp.service.UserService;
import com.jbp.utils.StrToMillsUtil;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

/**
 * 用户爵位(UserNobility)表服务实现类
 * @author cc
 * @since 2021-08-11 20:43:47
 */
@Service
public class UserNobilityServiceImpl extends ServiceImpl<UserNobilityDao, UserNobility> implements UserNobilityService {
    @Autowired
    private UserService userService;
    //升级经验
    public static final int[] upScores = {1000,15000,40000,90000,200000,500000,1000000};
    //保级经验
    public static final int[] keepScores = {0,0,20000,45000,100000,250000,500000};

    //增加积分
    @Override
    public void addScore(Integer userId, int addAcore) {
        QueryWrapper<UserNobility> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        UserNobility one = getOne(queryWrapper);
        if (one==null) {
            one = new UserNobility();
            one.setUserId(userId);
            one.setScore(0);
            one.setNobility(0);
            save(one);
        }

        int score = one.getScore()+addAcore;
        int level = one.getNobility();
        while (level<7 && score>= upScores[level]) {
            score -= upScores[level];
            level++ ;

            if (level>2) {
                Date startDate = new Date();
                Date endDate = DateUtils.addDays(startDate, 30);
                one.setStartTime(startDate);
                one.setEndTime(endDate);
            }
        }

        one.setNobility(level);
        one.setScore(score);
        one.setUpdateTime(new Date());
        updateById(one);

        updateUobility(one.getUserId(), one.getNobility());
    }

    //保级或降级
    @Override
    public void updateLevel(){
        QueryWrapper<UserNobility> queryWrapper = new QueryWrapper<>();
        queryWrapper.apply("UNIX_TIMESTAMP(end_time) < UNIX_TIMESTAMP('" + StrToMillsUtil.dateToStr(new Date()) + "')");
        queryWrapper.gt("nobility", 2);
        List<UserNobility> list = list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        for (UserNobility userNobility : list) {
            if (userNobility.getScore() < keepScores[userNobility.getNobility()-1]) {
                userNobility.setNobility(userNobility.getNobility()-1);
                updateUobility(userNobility.getUserId(), userNobility.getNobility());
                userNobility.setScore(0);
            } else if (userNobility.getNobility()>=7) {
                //国王以上保级成功 扣除保级经验
                userNobility.setScore(userNobility.getScore() - keepScores[userNobility.getNobility()-1]);
            } else {
                //其他保级 经验归零
                userNobility.setScore(0);
            }

            Date startDate = new Date();
            Date endDate = DateUtils.addDays(startDate, 30);
            userNobility.setStartTime(startDate);
            userNobility.setEndTime(endDate);
            userNobility.setUpdateTime(new Date());
            updateById(userNobility);
        }
    }

    @Override
    public UserNobility getUserNobility(Integer userId) {
        QueryWrapper<UserNobility> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        return getOne(queryWrapper);
    }

    public void updateUobility(Integer userId, int nobility) {
        User user = userService.getById(userId);
        if (user.getNobility()!=nobility) {
            user.setNobility(nobility);
            user.setUpdateTime(new Date());
            userService.updateById(user);
        }
    }

    public static void main(String[] args) {
        int score = 20000000;
        int level = 0;
        while (level<7 && score>= upScores[level]) {
            score -= upScores[level];
            level++ ;
        }
        System.out.println("l:"+level+" score:"+score);
    }
}